package com.zmn.oms.dubbo.impl.zmn.fund;

import com.zmn.common.utils.number.NumberUtil;
import com.zmn.oms.dubbo.dto.zmn.refund.FinalPriceOrderRefundDifferenceDIO;
import com.zmn.oms.model.dto.finalprice.RefundDifferenceDTO;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import org.apache.dubbo.config.annotation.Service;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.dubbo.dto.zmn.refund.ApplyRefundDIO;
import com.zmn.oms.dubbo.dto.zmn.refund.RefundDetailDRO;
import com.zmn.oms.dubbo.dto.zmn.refund.RefundProgressDRO;
import com.zmn.oms.dubbo.interfaces.zmn.refund.RefundOrderRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.dto.work.refund.RefundApplyDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.order.Order;
import com.zmn.oms.model.entity.refund.OrderWorkRefund;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.order.OrderService;
import com.zmn.oms.services.interfaces.refund.OrderWorkRefundService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.normal.business.interfaces.refund.RefundBService;
import com.zmn.pay.common.constant.PayConsts;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 类描述：退款实现类
 *
 * @author yule
 * @date 2020/04/21 17:35
 */
@Service(loadbalance = "roundrobin", timeout = 5000, retries = 2, version = DubboConsts.INTERFACE_VERSION)
public class RefundOrderRemoteServiceImpl implements RefundOrderRemoteService {

    private Logger logger = LoggerFactory.getLogger(RefundOrderRemoteServiceImpl.class);

    @Autowired
    OrderWorkService orderWorkService;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    OrderService orderService;
    @Autowired
    RefundBService refundBService;
    @Autowired
    OrderWorkRefundService orderWorkRefundService;
    @Autowired
    OrderPayService orderPayService;

    /**
     * 申请退款
     *
     * @param applyRefundDIO
     * @return
     */
    @Override
    public ResponseDTO applyRefund(ApplyRefundDIO applyRefundDIO) {
        Order order = orderService.findOrderByKey(applyRefundDIO.getOrderId());
        if (order == null) {
            return ResponseDTO.fail("订单不存在");
        }

        try {
            RefundApplyDTO refundApplyDTO = new RefundApplyDTO();
            refundApplyDTO.setOrderId(applyRefundDIO.getOrderId());
            refundApplyDTO.setWorkId(applyRefundDIO.getOrderId());
            refundApplyDTO.setApplyTime(DateUtil.getNow());
            refundApplyDTO.setReasonMap(applyRefundDIO.getReasonMap());
            refundApplyDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
            refundApplyDTO.setOperatorId(order.getUserId());
            OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(applyRefundDIO.getOrderId());
            refundApplyDTO.setOperator(StringUtils.defaultIfBlank(Optional.ofNullable(orderDetail).orElse(new OrderDetail()).getUserName(), "前端用户"));
            // 退款申请
            refundBService.applyRefund(refundApplyDTO);
        } catch (OmsBaseException e) {
            return ResponseDTO.fail(e.getMessage());
        } catch (Exception e) {
            logger.error("[{}]退款申请异常", applyRefundDIO.getOrderId(), e.getMessage(), e);
            return ResponseDTO.fail("申请退款失败");
        }

        return ResponseDTO.success();
    }

    /**
     * 退款明细
     *
     * @param orderId
     * @return
     */
    @Override
    public ResponseDTO<RefundDetailDRO> refundDetail(Long orderId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        // 显示用户退款状态
        Integer refundStatus = OrderConsts.getUserRefundStatus(NumberUtil.isNotNullOrZero(orderWork.getRefundTargetWorkId()), orderWork.getRefundReviewStatus(), orderWork.getPayStatus());
        // 申请金额-所支付的金额
        Integer applyAmount = 0;
        if (Objects.equals(orderWork.getPrepayStatus(), PayConsts.PAY_STATUS_DONE) && orderWork.getPrepayAmount() != null) {
            applyAmount = applyAmount + orderWork.getPrepayAmount();
        }
        if (Objects.equals(orderWork.getDepositStatus(), PayConsts.PAY_STATUS_DONE) && orderWork.getDepositAmount() != null) {
            applyAmount = applyAmount + orderWork.getDepositAmount();
        }

        // 实际退款金额- 退款成功才显示
        Integer actualAmount = null;
        if (Objects.equals(orderWork.getPayStatus(), PayConsts.REFUND_STATUS_DONE)) {
            List<OrderPay> orderPays = orderPayService.listOrderPayByOrderId(orderId);
            actualAmount = orderPays.stream()
                    .filter(e->Objects.equals(e.getTradeType(),PayConsts.PAY_TRADE_TYPE_REFUND))
                    .mapToInt(e -> e.getAmount())
                    .sum();
        }

        RefundDetailDRO refundDetailDRO = new RefundDetailDRO();
        refundDetailDRO.setOrderId(orderId);
        refundDetailDRO.setRefundStatus(refundStatus);
        refundDetailDRO.setApplyAmount(applyAmount);
        refundDetailDRO.setActualAmount(actualAmount);
        refundDetailDRO.setDiscountAmount(orderWork.getDiscountAmount());
        refundDetailDRO.setApplyTime(orderWork.getRefundApplyTime());
        refundDetailDRO.setRefundTime(orderWork.getRefundTime());
        refundDetailDRO.setRefundStatusName(PayConsts.getPayStatusName(refundStatus));

        // 退款进度
        if (refundStatus != null) {
            RefundProgressDRO step1 = new RefundProgressDRO(1, GlobalConsts.YES, orderWork.getRefundApplyTime());
            RefundProgressDRO step2 = new RefundProgressDRO(2, GlobalConsts.YES, orderWork.getRefundApplyTime());
            RefundProgressDRO step3 = new RefundProgressDRO(3, GlobalConsts.NO, orderWork.getRefundTime());
            // 已退款，最后个节点设置已处理
            if (Objects.equals(refundStatus, PayConsts.REFUND_STATUS_DONE)) {
                step3.setProcessFlag(GlobalConsts.YES);
            }
            refundDetailDRO.setRefundProgress(Lists.newArrayList(step1, step2, step3));
        }

        return ResponseDTO.success(refundDetailDRO);
    }

    @Override
    public ResponseDTO finalPriceOrderRefundDifference(FinalPriceOrderRefundDifferenceDIO finalPriceOrderRefundDifferenceDIO) {
        // 没人调用，saas通过验收接口退差额
        logger.info("一口价订单退差额#finalPriceOrderRefundDifferenceDIO={}", finalPriceOrderRefundDifferenceDIO);
        RefundDifferenceDTO refundDifferenceDTO = new RefundDifferenceDTO();
        refundDifferenceDTO.setOrderId(finalPriceOrderRefundDifferenceDIO.getOrderId());
        refundDifferenceDTO.setWorkId(finalPriceOrderRefundDifferenceDIO.getWorkId());
        refundDifferenceDTO.setRefundDifferenceAmount(finalPriceOrderRefundDifferenceDIO.getRefundAmount());
        try {
            refundBService.refundDifference(refundDifferenceDTO);
        } catch (OmsBaseException e) {
            return ResponseDTO.fail(e.getCode(), e.getMessage());
        }
        return ResponseDTO.success(finalPriceOrderRefundDifferenceDIO);
    }
}
